package com.ruoyi.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.business.bo.HcxCouponAddBo;
import com.ruoyi.business.bo.HcxCouponEditBo;
import com.ruoyi.business.bo.HcxCouponQueryBo;
import com.ruoyi.business.domain.HcxAppUser;
import com.ruoyi.business.domain.HcxCoupon;
import com.ruoyi.business.domain.HcxMerchantProduct;
import com.ruoyi.business.domain.HcxUserCoupon;
import com.ruoyi.business.mapper.HcxCouponMapper;
import com.ruoyi.business.service.IHcxAppUserService;
import com.ruoyi.business.service.IHcxCouponService;
import com.ruoyi.business.service.IHcxUserCouponService;
import com.ruoyi.business.vo.HcxCouponVo;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.AssertUtils;
import com.ruoyi.common.utils.PageUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 优惠券(平台发送全商家通用)Service业务层处理
 *
 * @author wsdz
 * @date 2022-08-17
 */
@Service
@AllArgsConstructor
public class HcxCouponServiceImpl extends ServicePlusImpl<HcxCouponMapper, HcxCoupon> implements IHcxCouponService {

    private final IHcxAppUserService appUserService;

    private final IHcxUserCouponService userCouponService;

    @Override

    public HcxCouponVo queryById(Long id) {
        return getVoById(id, HcxCouponVo.class);
    }

    @Override
    public TableDataInfo<HcxCouponVo> queryPageList(HcxCouponQueryBo bo) {
        PagePlus<HcxCoupon, HcxCouponVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), HcxCouponVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<HcxCouponVo> queryList(HcxCouponQueryBo bo) {
        return listVo(buildQueryWrapper(bo), HcxCouponVo.class);
    }

    private LambdaQueryWrapper<HcxCoupon> buildQueryWrapper(HcxCouponQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HcxCoupon> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getName()), HcxCoupon::getName, bo.getName());
        lqw.eq(bo.getBeginDate() != null, HcxCoupon::getBeginDate, bo.getBeginDate());
        lqw.eq(bo.getEndDate() != null, HcxCoupon::getEndDate, bo.getEndDate());

        lqw.apply(Validator.isNotEmpty(params.get("beginTime")),
                        "date_format(begin_date,'%y%m%d') >= date_format({0},'%y%m%d')",
                        params.get("beginTime"))
                .apply(Validator.isNotEmpty(params.get("endTime")),
                        "date_format(end_date,'%y%m%d') >= date_format({0},'%y%m%d')",
                        params.get("endTime"));
        lqw.eq(bo.getDenomination() != null, HcxCoupon::getDenomination, bo.getDenomination());
        lqw.eq(bo.getConditionPrice() != null, HcxCoupon::getConditionPrice, bo.getConditionPrice());
        lqw.eq(StrUtil.isNotBlank(bo.getUseIntroduce()), HcxCoupon::getUseIntroduce, bo.getUseIntroduce());
        lqw.eq(StrUtil.isNotBlank(bo.getDelFlag()), HcxCoupon::getDelFlag, bo.getDelFlag());
        return lqw;
    }

    @Override
    @Transactional
    public Boolean insertByAddBo(HcxCouponAddBo bo) {
        HcxCoupon add = BeanUtil.toBean(bo, HcxCoupon.class);
        validEntityBeforeSave(add);
        boolean result = save(add);
        // 给未冻结的app用户发送优惠券
        List<HcxAppUser> list = appUserService.list(new LambdaQueryWrapper<HcxAppUser>().ne(HcxAppUser::getStatus, Constants.FOUR));
        AssertUtils.isTrue(CollectionUtil.isNotEmpty(list), "还没有app用户,无法添加优惠券!");
        List<HcxUserCoupon> coupons = new ArrayList<>();
        for (HcxAppUser hcxAppUser : list) {
            HcxUserCoupon hcxUserCoupon = new HcxUserCoupon();
            hcxUserCoupon.setName(add.getName());
            hcxUserCoupon.setUserId(hcxAppUser.getId());
            hcxUserCoupon.setPhonenumber(hcxAppUser.getPhonenumber());
            hcxUserCoupon.setRealName(hcxAppUser.getRealName());
            hcxUserCoupon.setCouponId(add.getId());
            hcxUserCoupon.setStatus(Constants.ZERO);
            hcxUserCoupon.setBeginDate(add.getBeginDate());
            hcxUserCoupon.setEndDate(add.getEndDate());
            hcxUserCoupon.setDenomination(add.getDenomination());
            hcxUserCoupon.setConditionPrice(add.getConditionPrice());
            hcxUserCoupon.setUseIntroduce(add.getUseIntroduce());
            coupons.add(hcxUserCoupon);
        }
        result = userCouponService.saveBatch(coupons);
        return result;
    }

    @Override
    @Transactional
    public Boolean updateByEditBo(HcxCouponEditBo bo) {
        HcxCoupon update = BeanUtil.toBean(bo, HcxCoupon.class);
        validEntityBeforeSave(update);
        boolean result = updateById(update);
        // 修改用户拥有的优惠券面额
        List<HcxUserCoupon> list = userCouponService.list(new LambdaQueryWrapper<HcxUserCoupon>().eq(HcxUserCoupon::getCouponId, bo.getId()));
        for (HcxUserCoupon hcxUserCoupon : list) {
            hcxUserCoupon.setBeginDate(bo.getBeginDate());
            hcxUserCoupon.setEndDate(bo.getEndDate());
            hcxUserCoupon.setDenomination(bo.getDenomination());
            hcxUserCoupon.setConditionPrice(bo.getConditionPrice());
            hcxUserCoupon.setUseIntroduce(bo.getUseIntroduce());
        }
        if (CollectionUtil.isNotEmpty(list)) {
            result = userCouponService.updateBatchById(list);
        }
        return result;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(HcxCoupon entity) {

        // 判断优惠券名称是否存在
        HcxCoupon hcxCoupon = getOne(new LambdaQueryWrapper<HcxCoupon>()
                .eq(HcxCoupon::getName, entity.getName())
                .last("limit 1")
        );
        // 如果是新增操作
        if (ObjectUtil.isEmpty(entity.getId())) {
            AssertUtils.isTrue(ObjectUtil.isEmpty(hcxCoupon), "新增优惠券名称" + entity.getName() + ",失败，优惠券名称已存在");
        } else {
            if (ObjectUtil.isNotEmpty(hcxCoupon) && entity.getId().longValue() != hcxCoupon.getId().longValue()) {
                throw new CustomException("修改优惠券名称" + entity.getName() + ",失败，优惠券名称已存在");
            }
        }
    }

    @Override
    @Transactional
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        List<HcxUserCoupon> list = userCouponService.list(new LambdaQueryWrapper<HcxUserCoupon>().in(HcxUserCoupon::getCouponId, ids));
        List<Long> collect = list.stream().map(HcxUserCoupon::getId).collect(Collectors.toList());
        boolean result;
        // 删除用户的优惠券
        result = userCouponService.removeByIds(collect);
        // 删除
        result = removeByIds(ids);
        return result;
    }

    @Override
    public String importHcxCoupon(List<HcxCouponVo> hcxCouponList) {
        AssertUtils.isTrue(CollectionUtils.isNotEmpty(hcxCouponList), "导入数据不能为空");
        int successNum = 0;
        for (HcxCouponVo hcxCoupon : hcxCouponList) {
            HcxCoupon add = BeanUtil.toBean(hcxCoupon, HcxCoupon.class);
            save(add);
            successNum++;
        }
        String msg = String.format("导入完成，共计 %d 条数据，成功 %d 条！", hcxCouponList.size(), successNum);
        if (successNum != hcxCouponList.size()) {
            msg = msg + String.format("失败 %d 条！", hcxCouponList.size() - successNum);
        }
        return msg;
    }
}
